using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.PageFlow;
using System.Globalization;

namespace WCSFContrib.PageFlow.Xml
{
    public class NavigationGraph
    {
        private string _name;
        private IXmlPageFlowInstanceStore _instanceStore;
        private View _startView;
        private string _abortUrl;
        private AbandonBehavior _abandonable;
        private string _notRunningUrl;
        private List<View> _views;
        private bool _constrained;
        private Type _pageFlowType;

        public NavigationGraph()
        {
            this._views = new List<View>();
        }

        public NavigationGraph(string name, IXmlPageFlowInstanceStore instanceStore, View startView, string abortUrl, AbandonBehavior abandonable, string notRunningUrl, Type pageFlowType)
        {
            this._name = name;
            this._instanceStore = instanceStore;
            this._startView = startView;
            this._abortUrl = abortUrl;
            this._abandonable = abandonable;
            this._notRunningUrl = notRunningUrl;
            this._pageFlowType = pageFlowType;

            this._views = new List<View>();
        }

        public Type PageFlowType
        {
            get { return _pageFlowType; }
            set { _pageFlowType = value; }
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public IXmlPageFlowInstanceStore InstanceStore
        {
            get { return _instanceStore; }
            set { _instanceStore = value; }
        }

        public View StartView
        {
            get { return _startView; }
            set { _startView = value; }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")]
        public string AbortUrl
        {
            get { return _abortUrl; }
            set { _abortUrl = value; }
        }

        public AbandonBehavior Abandonable
        {
            get { return _abandonable; }
            set { _abandonable = value; }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")]
        public string NotRunningUrl
        {
            get { return _notRunningUrl; }
            set { _notRunningUrl = value; }
        }

        public IList<View> Views
        {
            get { return _views; }
        }

        public bool Constrained
        {
            get { return _constrained; }
            set { _constrained = value; }
        }

        public View TryGetViewFromName(string viewName)
        {
            string tempViewName = viewName.ToLower(CultureInfo.CurrentCulture);

            return _views.Find(delegate(View view)
                    {
                        return view.Name.ToLower(CultureInfo.CurrentCulture) == tempViewName;
                    });
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#")]
        public View TryGetViewFromUrl(string url)
        {
            if (url == null)
                return null;

            string tempViewUrl = url.ToLower(CultureInfo.CurrentCulture);

            return _views.Find(delegate(View view)
                    {
                        return view.Url.ToLower(CultureInfo.CurrentCulture) == tempViewUrl;
                    });
        }

        public bool ContainsView(string viewName)
        {
            return TryGetViewFromName(viewName) != null;
        }
    }

    public class View
    {
        private string _name;
        private string _url;
        private List<Transition> _transitions;

        public View(string name, string url)
        {
            this._name = name;
            this._url = url;

            this._transitions = new List<Transition>();
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")]
        public string Url
        {
            get { return _url; }
            set { _url = value; }
        }

        public IList<Transition> Transitions
        {
            get { return _transitions; }
        }

        public Transition TryGetTransitionFromTransitionName(string transitionName)
        {
            string tempTransitionName = transitionName.ToLower(CultureInfo.CurrentCulture);

            return _transitions.Find(delegate(Transition transition)
                    {
                        return transition.Name.ToLower(CultureInfo.CurrentCulture) == tempTransitionName;
                    });
        }

        public View TryGetViewFromTransitionName(string transitionName)
        {
            string tempTransitionName = transitionName.ToLower(CultureInfo.CurrentCulture);

            Transition tempTransition = _transitions.Find(delegate(Transition transition)
                    {
                        return transition.Name.ToLower(CultureInfo.CurrentCulture) == tempTransitionName;
                    });

            return tempTransition.View;
        }

        public bool ContainsTransition(string transitionName)
        {
            return TryGetTransitionFromTransitionName(transitionName) != null;
        }
    }

    public class Transition
    {
        private string _name;
        private View _view;
        private string _condition;

        public Transition(string name, View view, string condition)
        {
            this._name = name;
            this._view = view;
            this._condition = condition;
        }

        public Transition(string name, View view)
        {
            this._name = name;
            this._view = view;
        }

        public Transition(string name, string condition)
        {
            this._name = name;
            this._condition = condition;
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public View View
        {
            get { return _view; }
            set { _view = value; }
        }

        public string Condition
        {
            get { return _condition; }
            set { _condition = value; }
        }

    }

    internal class EqualityLowerComparer<T> : IEqualityComparer<string>
    {
        #region IEqualityComparer<string> Members

        public bool Equals(string x, string y)
        {
            return x.ToLower(CultureInfo.CurrentCulture) == y.ToLower(CultureInfo.CurrentCulture);
        }

        public int GetHashCode(string obj)
        {
            return base.GetHashCode();
        }

        #endregion
    }
}
